﻿//-------------------------------------------------------------------------------
// Name:        OCRnew
// Purpose:     Deze OCR kijkt naar de overgang naar zwart per pixelregel.
//              En vergelijkt die met opgeslagen waarden.
//
// Usage:       1. use the learn method on some characters
//              2. recognize the letter with the method regonize
//
//
// Authors:     Hessel Meulenbeld
//              Guido van Hienen
//
// Created:     9-03-2012
//-------------------------------------------------------------------------------

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;

namespace THO7AlgoritmTimerApplication {
    class OCRnew {
        /// <summary>
        /// Deze OCR kijkt naar de overgang naar zwart per pixelregel.
        /// En vergelijkt die met opgeslagen waarden.
        /// </summary>
        public letter[] regonize(Bitmap sourceImage, String file,String dir,int return_aantal) {
            //ik ga ervan uit dat de letters die vergeleken moeten worden net zo staan als de leer afbeeldingen
            //dus als de leerafbeeldingen scheef staan dan kan hij alleen scheefe letters herkennen
            //bestand uitlezen en naar een buffer schrijven.
            if (!File.Exists(file)) {
                FileStream fs = File.Create(file);
                fs.Close();
            }
            StreamReader reader = new StreamReader(file);
            List<String> characters = new List<String>();
            //lees het bestand uit
            String s = "";
            while ((s = reader.ReadLine()) != null) {
                characters.Add(s);
            }
            reader.Close();

            //plaatje bekijken
            Bitmap returnImage = new Bitmap(sourceImage);
            VisionAlgorithm fp = new find_pixel("");
            returnImage = fp.DoAlgorithm(returnImage);
            if (dir == "links") {
                VisionAlgorithm stretch = new stretch("", 150, 100);
                returnImage = stretch.DoAlgorithm(returnImage);
            } else {
                VisionAlgorithm stretch = new stretch("", 100, 150);
                returnImage = stretch.DoAlgorithm(returnImage);
            }

            int[] overgangen = new int[returnImage.Height];
            zoek_overgangen(returnImage,out overgangen);

            //kijk bij wie hij het dichtst in de buurt komt
            int[] hoogsten = new int[return_aantal];
            letter[] hoogste = new letter[return_aantal];
            for (int q = 0; q < hoogste.Length; q++) {
                hoogsten[q] = 0;
                hoogste[q] = new letter("?", 0);
            }
            for (int i = 0; i < characters.Count; i++) {
                //haal eerst de waardes uit de string van het tekst document
                string[] words = characters[i].Split(' ');
                int[] f = new int[words.Length];
                for (int j = 1; j < words.Length; j++) {
                    f[j-1] = int.Parse(words[j]);
                }
                //bekijk hoeveel vlakken overeen komen
                //eerst zat ik afwijkingen bij elkaar op te tellen maar dat komt op hetzelfde neer als het hele de afwijking bekijken
                int goed = 0;
                for (int j = 0; j < returnImage.Height; j++) {
                    int temp = overgangen[j] - f[j];
                    if (temp < 1000 && temp > -1000) {
                        goed += 1;
                    }
                }
                Array.Sort(hoogsten);
                if (goed > hoogsten[0]) {
                    for (int l = 0; l < hoogste.Length; l++) {
                        if (hoogste[l].get_waarde() == hoogsten[0]) {
                            hoogste[l] = new letter(words[0], goed);
                            break;
                        }
                    }
                    hoogsten[0] = goed;
                }
            }
            return hoogste;
        }
        public Bitmap learn(Bitmap sourceImage, String character, out letter[] output,String file,String dir,int return_aantal) {
            //kijken of de file met waardes al bestaat, maak hem aan als hij niet bestaat.
            if (!File.Exists(file)) {
                FileStream fs = File.Create(file);
                fs.Close();
            }
            //maak een reader aan het lees het bestand met waardes uit.
            StreamReader reader = new StreamReader(file);
            List<String> characters = new List<String>();
            //lees het bestand uit
            String s = "";
            while ((s = reader.ReadLine()) != null) {
                characters.Add(s);
            }
            reader.Close();

            //plaatje pakken
            Bitmap returnImage = new Bitmap(sourceImage);
            
            // witte randen verwijderen met visionalgorithme
            VisionAlgorithm fp = new find_pixel("");
            returnImage = fp.DoAlgorithm(returnImage);
            
            //kijken vanaf welke kant gekeken moet worden en afbeelding daarvoor geschikt maken.
            if (dir == "links") {
                VisionAlgorithm stretch = new stretch("", 150, 100);
                returnImage = stretch.DoAlgorithm(returnImage);
            } else {
                VisionAlgorithm stretch = new stretch("", 100, 150);
                returnImage = stretch.DoAlgorithm(returnImage);
            }
           
            //zoeken naar overgangen naar zwart in de afbeelding.
            int[] overgangen = new int[returnImage.Height];
            zoek_overgangen(returnImage, out overgangen);
   

            //kijk of er al een is die dezelfde letter heeft.
            Boolean gevonden = false;
            for (int i = 0; i < characters.Count; i++) {
                if (characters[i][0] == character[0]) {
                    //combineer de waardes
                    //haal eerst de waardes uit de string van het tekst document
                    string[] words = characters[i].Split(' ');
                    int[] f = new int[words.Length];
                    for (int j = 1; j < words.Length; j++) {
                        f[j-1] = int.Parse(words[j]);
                    }
                    String temp = character;
                    for (int j = 0; j < f.Length-2; j++) {
                        f[j] = ((f[j]*f[f.Length-2] + overgangen[j]) / (f[f.Length-2]+1));
                        temp += " " + f[j];
                    }
                    f[f.Length-2]++;
                    temp += " " + f[f.Length-2];
                    characters[i] = temp;
                    gevonden = true;
                    break;
                }
            }
            if (!gevonden) {
                String waardes = character;
                for (int j = 0; j < (returnImage.Height); j++) {
                    waardes += " " + overgangen[j];
                }
                waardes += " " + 1;
                characters.Add(waardes);
            }
            //schrijf nu alle waardes terug naar de tekst file
            StreamWriter writer = new StreamWriter(file);
            for (int i = 0; i < characters.Count; i++) {
                writer.WriteLine(characters[i]);
            }
            writer.Close();
            output = regonize(sourceImage,file,dir,return_aantal);
            return returnImage;
        }
        public void zoek_overgangen(Bitmap input, out int[] overgang) {
            //lock data
            Rectangle rect = new Rectangle(0, 0, input.Width, input.Height);
            BitmapData myBmpData = input.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            IntPtr ptr = myBmpData.Scan0;
            int numBytes = input.Width * input.Height * 3;
            byte[] rgbValues = new byte[numBytes];
            System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, numBytes);

            //zoeken naar de overgang naar zwart, een gevonden overgang + 1000.
            overgang = new int[input.Height];
            for (int i = 0; i < input.Height; i++) {
                bool start = false;
                for (int j = 0; j < input.Width * 3; j += 3) {
                    if (!start) {
                        if (rgbValues[(i * input.Width * 3) + j] == 0) {
                            start = true;
                            overgang[i] += 1000;
                        }
                    } else {
                        if (rgbValues[(i * input.Width * 3) + j] == 255) {
                            start = false;
                        }
                    }
                }
            }
            //data unlocken
            System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, numBytes);
            input.UnlockBits(myBmpData);
        }
    }
    public class letter {
        /// <summary>
        // de klasse letter slaat per letter de letter zelf en de bijbehorende waarde op die er aan gegeven is.
        // de waarde is de overeenkomt van de letter met de opgeslagen waarden.
        /// </summary>
        String letter1 = "";
        int waarde = 0;
        public letter(String l, int w) {
            letter1 = l;
            waarde = w;
        }
        public int get_waarde() {
            return waarde;
        }
        public String get_letter() {
            return letter1;
        }
    }
}
